package com.smart.manager.pop.repository;

import cn.hutool.core.lang.Opt;
import com.smart.common.entities.core.BaseSearch;
import com.smart.common.entities.core.Page;
import com.smart.manager.member.entities.models.query.QMemberProfileAccount;
import com.smart.manager.member.entities.views.MemberView;
import com.smart.manager.pop.entities.assembler.Reward;
import com.smart.manager.pop.entities.body.RActivityRecord;
import com.smart.manager.pop.entities.models.PopC2cAttend;
import com.smart.manager.pop.entities.models.PopActivityMain;
import com.smart.manager.pop.entities.models.PopC2cRecord;
import com.smart.manager.pop.entities.models.query.QPopC2cAttend;
import com.smart.manager.pop.entities.models.query.QPopC2cRecord;
import com.smart.manager.pop.entities.views.ActivityMainView;
import com.smart.service.remind.RemindService;
import com.smart.utils.SqlUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * 注册活动-达成管理
 *
 * @author Administrator
 */

@Log4j2
@Service
@RequiredArgsConstructor
public class ActivityRecordRepository {

    private final RemindService remindService ;

    public Page<PopC2cRecord> pageList(RActivityRecord.SearchBody search) {
        QPopC2cRecord query = new QPopC2cRecord();
        Opt.ofNullable(search.getActivityId()).ifPresent(x -> query.activity.id.eq(x));
        Opt.ofBlankAble(search.getActivityTitle()).ifPresent(x -> query.activity.title.contains(x));
        Opt.ofNullable(search.getInviterId()).ifPresent(x -> query.inviter.id.eq(x));
        Opt.ofBlankAble(search.getInviterPhoneNumber()).ifPresent(x -> query.inviter.phoneNumber.contains(x));
        Opt.ofBlankAble(search.getActorPhoneNumber()).ifPresent(x -> query.actor.phoneNumber.contains(x));
        Opt.ofBlankAble(search.getDateRange()).ifPresent(x -> {
            LocalDateTime[] times = SqlUtil.formatDateTimeRange(x);
            query.achievedTime.between(times[0], times[1]);

        });

        query.setFirstRow(search.firstRow()).setMaxRows(search.maxRows()).order().id.desc();
        return new Page<PopC2cRecord>().load(query.findPagedList());
    }

    /**
     * 保存活动达成记录
     *
     * @param activity  活动信息
     * @param inviterId 被邀请人ID
     * @param actorId   参与人Id
     */
    @Async
    public void saveRecord(PopActivityMain activity, Long inviterId, Long actorId) {
        //记录推广达成
        ActivityMainView activityMainView = new ActivityMainView().setId(activity.getId());
        MemberView inviter = new MemberView().setId(inviterId);
        MemberView actor = new MemberView().setId(actorId);
        PopC2cAttend inviterRecord = new QPopC2cAttend().activity.id.eq(activity.getId()).member.eq(inviter).setMaxRows(1).findOne();
        //本次活动邀请后的人头数
        Integer newRts = inviterRecord.getAchievedTotal() + 1;
        inviterRecord.setAchievedTotal(newRts);
        Reward reward = activity.getReward();

        //判断能否发放奖励 当前邀请人数和环节平均值的余数为0时 就能发放数据
        boolean canSend = calcCanSend(  reward, newRts, inviterRecord.getPrizeTotal());
        //保存邀请达成数据
        new PopC2cRecord().setActivity(activityMainView).setAchievedTime(LocalDateTime.now()).setInviter(inviter).setActor(actor).setXh(newRts).setPrizeAttr(canSend).save();
        if (canSend) {
            //是否需要判断上限
            switch (reward.getRule()) {
                case R1:
                    sendMedalToInviter(inviterId, reward);
                    break;
                case R2:
                    sendCoinToInviter(inviterId, reward);
                    break;
                case R3:
                    sendPowerToInviter(inviterId, reward);
                    break;
            }
            //增加一次获得的奖品数量
            inviterRecord.setPrizeTotal(inviterRecord.getPrizeTotal() + 1);
        }
        inviterRecord.setAchievedTotal(newRts);
        // 更新推广成就数据
        inviterRecord.update();


    }


    /**
     * 计算是否触发奖励
     *

     * @param reward     奖励触发规则
     * @param newXh      当前注册人的序号
     * @param prizeTotal 邀请人当前已经获取的奖励次数
     * @return boolean 是否触发奖励
     */
    private boolean calcCanSend(  Reward reward, int newXh, int prizeTotal) {

        boolean exp = newXh % reward.getAchievedQuantity() == 0;
        // 不在奖励节点 不触发奖励
        if (!exp) {
            return false;
        }
        //如果不限制领奖次数 那么返回允许奖触发奖励
        if (reward.getMostQuantity() == 0) {
            return true;
        }
        //否则只有在已经获取奖励的数量小于最多领取次数的时候 触发奖励
        return prizeTotal < reward.getMostQuantity();


    }

    /**
     * 给邀请人发发放钻石
     *
     * @param inviterId 邀请人ID
     * @param reward    奖品对象
     */
    private void sendMedalToInviter(Long inviterId, Reward reward) {
        String field = QMemberProfileAccount.Alias.medalBalance.toString();
        String sqlExpr = String.format("%s = %s + %s", field, field, reward.getRewardQuantity());
        new QMemberProfileAccount().member.id.eq(inviterId).asUpdate().setRaw(sqlExpr).update();
        remindService.sendMsgWhenGetDiamond( inviterId , reward.getRewardQuantity());


    }


    /**
     * 给邀请人发放金币
     *
     * @param inviterId 邀请人ID
     * @param reward    奖品对象
     */
    private void sendCoinToInviter(Long inviterId, Reward reward) {
        String field = QMemberProfileAccount.Alias.coinBalance.toString();
        String sqlExpr = String.format("%s = %s + %s", field, field, reward.getRewardQuantity());
        new QMemberProfileAccount().member.id.eq(inviterId).asUpdate().setRaw(sqlExpr).update();
        log.warn("需要写一个日志");
    }

    /**
     * 给邀请人发放能量
     *
     * @param inviterId 邀请人ID
     * @param reward    奖品对象
     */
    private void sendPowerToInviter(Long inviterId, Reward reward) {
        String field = QMemberProfileAccount.Alias.powerBalance.toString();
        String sqlExpr = String.format("%s = %s + %s", field, field, reward.getRewardQuantity());
        new QMemberProfileAccount().member.id.eq(inviterId).asUpdate().setRaw(sqlExpr).update();
        log.warn("需要写一个日志");
    }

    public Page<PopC2cRecord> getMyRecordList(Long memberId , BaseSearch search) {
        QPopC2cRecord query = new QPopC2cRecord();
        query.inviter.id.eq(memberId)   .setFirstRow(search.firstRow()).setMaxRows(search.maxRows()).order().id.desc();
        return new Page<PopC2cRecord>().load(query.findPagedList());
    }




}
